﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using NHibernate;
using NHibernate.Linq;
using MSH.Common.Business;
using MSH.Common.Helpers;

namespace MSH.Common.Helpers
{
    /// <summary>
    /// Deze helper is verantwoordelijk voor alles wat te maken heeft met de sessies van ingelogde gebruikers.
    /// </summary>
    public static class SessionHelper
    {

        static SessionHelper()
        {

        }

        /// <summary>
        /// Ophalen van een sessie aan de hand van de gebruikersnaam
        /// </summary>
        /// <param name="username">Gebruikersnaam</param>
        /// <returns>UserSession van de gebruikersnaam, of NULL als er geen UserSession is</returns>
        public static UserSession GetSessionByUsername(String username)
        {
            ISession session = NHibernateHelper.GetSessionFactory().OpenSession();
            UserSession us = null;
            try
            {
                us = session.Query<UserSession>().Where(u => u.Username == username).First<UserSession>();
            }
            catch (Exception e)
            {
                LogHelper.LogMessage("SessionHelper.GetSessionByUsername(): " + e);
                return null;
            }
            return us;
        }

        /// <summary>
        /// Ophalen van een sessie aan de hand van de token
        /// </summary>
        /// <param name="token">Token ingelogde gebruiker</param>
        /// <returns>Sessie van het token, of NULL als er geen UserSession is</returns>
        public static UserSession GetSessionByToken(String token)
        {
            ISession session = NHibernateHelper.GetCurrentSession();
            UserSession us = null;
            try
            {
                us = session.Query<UserSession>().Where(u => u.Token == token).First<UserSession>();
            }
            catch
            {
                return null;
            }
            return us;
        }

        /// <summary>
        /// Verwijder een sessie aan de hand van de gebruikersnaam
        /// </summary>
        /// <param name="username">Gebruikersnaam</param>
        /// <returns>Verwijderde sessie</returns>
        public static UserSession DeleteSessionByUsername(String username)
        {
            ISession session = NHibernateHelper.GetCurrentSession();
            UserSession us = null;
            try
            {
                us = session.Query<UserSession>().Where(u => u.Username == username).First<UserSession>();

                session.Delete(us);

                using (ITransaction trans = session.BeginTransaction())
                {
                    trans.Commit();
                }
            }
            catch (Exception e)
            {
                LogHelper.LogMessage("SessionHelper.DeleteSessionByUsername(): " + e);
                return null;
            }

            return us;
        }

        /// <summary>
        /// Update de tijd van de laatste locatie update.
        /// </summary>
        /// <param name="token">Token van ingelogde gebruiker</param>
        /// <param name="dt">Tijd van de laatste locatie update</param>
        public static void UpdateSessionLastLocationUpdate(String token, DateTime dt)
        {
            ISession session = NHibernateHelper.GetCurrentSession();
            try
            {
                UserSession us = session.Query<UserSession>().Where(u => u.Token == token).FirstOrDefault<UserSession>();
                us.LastLocationUpdate = dt;
                session.Save(us);

                using (ITransaction trans = session.BeginTransaction())
                {
                    trans.Commit();
                }
            }
            catch (Exception e)
            {
                LogHelper.LogMessage("SessionHelper.UpdateSessionLastLocationUpdate(): " + e);
            }
        }

        /// <summary>
        /// Opvragen of er een gebruiker ingelogd is met het meegegeven token.
        /// </summary>
        /// <param name="token">Token</param>
        /// <returns>Bool of het token valide is</returns>
        public static bool IsTokenValid(String token)
        {
            ISession session = NHibernateHelper.GetCurrentSession();
            int count = session.Query<UserSession>().Where(u => u.Token == token).Count();
            if (count > 0)
                return true;
            else
                return false;

        }

        /// <summary>
        /// Opvragen of een persoon in de buurt is geweest.
        /// </summary>
        /// <param name="token">Token van de ingelogde gebruiker</param>
        /// <param name="username">Gebruikersnaam van de persoon die in de buurt was</param>
        /// <returns>Boolean of de persoon in de buurt geweest is.</returns>
        public static bool WasPersonNearby(String token, String username)
        {
            if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(username))
                return false;

            ISession session = NHibernateHelper.GetCurrentSession();
            IQuery q = session.CreateSQLQuery("select 1 from usersession us " +
                                                "inner join personnearby pn ON pn.usersession = us.id " +
                                                string.Format("where us.token = '{0}' AND pn.username = '{1}'", token, username));
            q.UniqueResult();
            if (q.ToString().Equals("1"))
                return true;
            else
                return false;

        }
    }

}
